﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using zhWeb;
using System.DirectoryServices;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.ComponentModel;

namespace hzWeb.ChatRoomEventReceiver
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class ChatRoomEventReceiver : SPItemEventReceiver
    {
       // http://sharepoint2010/_layouts/hzWeb/UserPhoto.ashx?alias=chengcheng
       // http://sharepoint2010/SiteCollectionImages/chengcheng.png
       /// <summary>
       /// An item is being added.
       /// </summary>
       public override void ItemAdding(SPItemEventProperties properties)
       {
           if (properties.List == null ||properties.List.BaseTemplate.ToString() != "999") return;
           Helper.WriteLog("Entry ItemAdding");
           Config.webUrl = properties.WebUrl;
           string roomName = properties.AfterProperties["RoomName"].ToString();
           Helper.WriteLog("roomName is" + roomName);
           properties.AfterProperties.ChangedProperties.Add("Title", properties.AfterProperties["RoomName"].ToString());
           base.ItemAdding(properties);
           string adminSGId = "PCRoomManagers";
           string memberSGId = "PCRoomMembers";
           string meetingRoomId = string.Empty;
            
           SPSecurity.RunWithElevatedPrivileges(delegate()
           {
              
               try
               {
                   // MeetingSubject
                   string meetingSubject = properties.AfterProperties["MeetingSubject"].ToString();
                  // Create five year meeting room
                   string meetRoomUrl = this.CreateFiveYearsMeetingRooom(meetingSubject);
                   //string meetRoomUrl = "https://meet.ITFirst.com/test2/CC" + DateTime.Now.ToString("MMddmmss"); // only for testing
                   meetingRoomId = this.GetMeetRoomIDFromUrl(meetRoomUrl);
                   adminSGId = adminSGId + meetingRoomId;
                   memberSGId = memberSGId + meetingRoomId;
                   string ou = Config.Instance.chatRoomOU;

                   // Create the SG for chat room
                    Helper.WriteLog("Create adminGroupPath " + adminSGId);
                    string adminGroupPath = CreateSG(adminSGId, ou, Config.Instance.adminGroupsPath);
                    Helper.WriteLog("Create memberSGId " + memberSGId);
                    string memberGroupPath =  CreateSG(memberSGId, ou, Config.Instance.memberGroupPath);

                   // Add the user into AD group 
                    SPFieldUserValueCollection chatRoomAdmins = new SPFieldUserValueCollection(properties.Web, properties.AfterProperties["ChatRoomAdmins"].ToString());
                    ADManager adMamager = new ADManager(); 
                    adMamager.SearchADByAlias(adminSGId, Config.Instance.domainName, true);
                    Helper.WriteLog("Add users to adminGroupPath " + adminGroupPath);
                    this.AddUsersIntoSGGroup(chatRoomAdmins, adminGroupPath, properties.Web);
                    SPFieldUserValueCollection chatRoomMembers = new SPFieldUserValueCollection(properties.Web, properties.AfterProperties["ChatRoomMembers"].ToString());
                    adMamager.SearchADByAlias(memberSGId, Config.Instance.domainName, true);
                    Helper.WriteLog("Add users to memberGroupPath " + memberGroupPath);
                    this.AddUsersIntoSGGroup(chatRoomMembers, memberGroupPath, properties.Web);

                   // Create site for chat room
                    Helper.WriteLog("Create site with meetingRoomId " + meetingRoomId);
                    string spaceUrl = CreateSite(meetingRoomId, roomName, properties.Web.Site);
                    // string spaceUrl = properties.WebUrl + "/" + meetingRoomId;

                   // Create SharePoint groups for SG groups TBD
                   CreateSPGroup(adminSGId);
                   CreateSPGroup(memberSGId);

                   // Add supuer admin into adminSGId and memberSGId
                   this.AddUserIntoSGGroup(Config.Instance.supperAdminGroup, adminSGId);
                   this.AddUserIntoSGGroup(Config.Instance.supperAdminGroup, memberSGId);
                   this.AddUserIntoSGGroup(adminSGId, memberSGId);

                   // Update the list fields, like SG Name, Chat ID, Site Url
                   properties.AfterProperties.ChangedProperties.Add("ChatRoomID", meetingRoomId);
                   properties.AfterProperties.ChangedProperties.Add("ChatRoomSecurityGroupAdmin", adminSGId);
                   properties.AfterProperties.ChangedProperties.Add("ChatRoomSecurityGroupMember", memberSGId);
                   properties.AfterProperties.ChangedProperties.Add("ChatRoomSite", spaceUrl);
                   properties.AfterProperties.ChangedProperties.Add("MeetingRoomUrl", meetRoomUrl);
                   this.UpdateSIP(properties);  

                   // Create room in lync
                   Helper.WriteLog(string.Format("CreateRoomInLync with {0}, {1}, {2}, {3}, {4} ", adminGroupPath, memberGroupPath, roomName, memberSGId, spaceUrl));
                   CreateRoomInLync(adminGroupPath, memberGroupPath, roomName, memberSGId, spaceUrl);
               }
               catch (Exception ex)
               {
                   Helper.WriteLog("Exception from ItemAdding:" + ex.Message + ", StackTrace:" + ex.StackTrace);
                   properties.ErrorMessage = ex.Message;
                   properties.AfterProperties.ChangedProperties.Add("RoomStatus", ex.Message);
               }              

           });

           string siteUrl = properties.Web.Site.Url;
           string webUrl = properties.Web.Url.Replace(siteUrl, "");
           if (webUrl.Length > 0 && webUrl[0].ToString() == "/")
           {
               webUrl = webUrl.Substring(1);
           }

           if (webUrl.Length >0 && webUrl.LastIndexOf("/") == webUrl.Length - 1)
           {
               webUrl = webUrl.Substring(0, webUrl.Length -1);
           }

           if (string.IsNullOrEmpty(webUrl))
           {
               webUrl = meetingRoomId;
           }
           else
           {
               webUrl = webUrl + "/" + meetingRoomId;
           }

           using (SPWeb web = properties.Web.Site.OpenWeb(meetingRoomId))
           {
               // Update Documents.aspx
               if (web.Exists)
               {
                   // string[] fieldsForDocuments = { "DocIcon", "LinkFilename", "Author", "Created" };
                   // Helper.UpdateListViewWebPart(web, "pages/Documents.aspx", fieldsForDocuments, "Documents", "All Documents");

                   // string[] fieldsForMR = { "DocIcon", "LinkFilename", "FileSizeDisplay", "_x53c2__x4f1a__x4eba__x5458_", "Author", "_x65e5__x671f_" };
                   // Helper.UpdateListViewWebPart(web, "pages/MeetingRecords.aspx", fieldsForMR, "MeetingRecords", "All Documents");
               }
           }
       }
       
       
       private void UpdateSIP(SPItemEventProperties properties)
       {        
           string sip = string.Empty;
           string admins = properties.AfterProperties["ChatRoomAdmins"] == null ? properties.ListItem["ChatRoomAdmins"].ToString() : properties.AfterProperties["ChatRoomAdmins"].ToString();
           string members = properties.AfterProperties["ChatRoomMembers"] == null ? properties.ListItem["ChatRoomMembers"].ToString() : properties.AfterProperties["ChatRoomMembers"].ToString(); ;
           Dictionary<string, string> userSIP = new Dictionary<string, string>();
           this.GetSIP(admins, userSIP, properties.Web);
           this.GetSIP(members, userSIP, properties.Web);
           sip = this.GetSIPString(userSIP);
           properties.AfterProperties.ChangedProperties.Add("SIP", sip);                       
       }

       private string GetSIPString(Dictionary<string, string> userSIP)
       {
           StringBuilder sb = new StringBuilder();
           foreach (var sip in userSIP)
           {
               sb.Append(sip.Key + "#" + sip.Value + ";");
           }

           return sb.ToString();
       }

       private void GetSIP(string users, Dictionary<string, string> sips, SPWeb web)
       {
           ADManager adMamager = new ADManager();   
            SPSecurity.RunWithElevatedPrivileges(delegate()
           {
               using(SPSite site = new SPSite(web.Site.ID))
               {
                   web = site.OpenWeb();
                       List<SPUser> usersList = this.GetUserList(users, web);
                       foreach (var user in usersList)
                       {
                           if (!sips.ContainsKey(user.ID.ToString()))
                           {
                               // sips.Add(user.ID.ToString(), user.Email);
                               string alias = user.LoginName;
                               if (alias.Split("\\".ToCharArray()).Length == 2)
                               {
                                   alias = alias.Split("\\".ToCharArray())[1];
                               }

                              DirectoryEntry adUser = adMamager.SearchADByAlias(alias, Config.Instance.domainName);
                              var proxyAdress = adUser.Properties["proxyAddresses"];
                               bool foundSIP = false;
                              foreach (var proxy in proxyAdress)
                              {
                                  if (proxy != null && proxy.ToString().ToUpper().StartsWith("SIP"))
                                  {
                                      sips.Add(user.ID.ToString(), proxy.ToString());
                                      foundSIP = true;
                                      break;
                                  }
                              }

                              if (!foundSIP)
                              {
                                  throw new Exception("用户" + user.LoginName + "没有Lync帐号，不添加到群组");
                              }

                               //   var bytes = searchResult.Properties["thumbnailPhoto"][0] as byte[];
                              var photoUrl = string.Empty;
                              var department = string.Empty;
                              var title = string.Empty;
                              if (adUser.Properties["thumbnailPhoto"].Count != 0)
                              {
                                  var bytes = adUser.Properties["thumbnailPhoto"][0] as byte[];
                                  if (bytes != null)
                                  {
                                      string filePath = "/SiteCollectionImages/" + alias + ".jpg";
                                      SPFile file = web.GetFile(filePath);
                                          
                                      if (!file.Exists)
                                      {
                                          web.Site.RootWeb.Files.Add(filePath, bytes);
                                      }

                                      photoUrl = web.Site.Url + filePath;
                                  }                      
                              }

                              if (adUser.Properties["department"].Count != 0)
                              {
                                  department = adUser.Properties["department"][0].ToString();
                              }

                              if (adUser.Properties["title"].Count != 0)
                              {
                                  title = adUser.Properties["title"][0].ToString();
                              }
                 
                              SPItem userItem = web.SiteUserInfoList.GetItemById(user.ID);
                              if (!string.IsNullOrEmpty(photoUrl))
                              {
                                  userItem["Picture"] = photoUrl;
                              }

                              if (!string.IsNullOrEmpty(department))
                              {
                                  userItem["Department"] = department;
                              }
                              if (!string.IsNullOrEmpty(title))
                              {
                                  userItem["JobTitle"] = title;
                              }

                              userItem.Update();              
                       }
                   }
             }
           });
       }

       private void AddUsersIntoSGGroup(SPFieldUserValueCollection users, string groupPath, SPWeb web)
       {
           ADManager adMamager = new ADManager();        
           foreach (SPFieldUserValue user in users)
           {

               SPUser spUser = null; 
               if (user.LookupId == -1)
               {
                   spUser = web.EnsureUser(user.LookupValue);
               }
               else
               {
                   spUser = user.User;
               }


               string alias = spUser.LoginName.Substring(spUser.LoginName.IndexOf("\\") + 1);


               DirectoryEntry userEntry = adMamager.SearchADByAlias(alias, Config.Instance.domainName);
              adMamager.AddToGroup(userEntry.Path, groupPath);
           }
       }

       private void AddUserIntoSGGroup(string useralias, string groupalias)
       {
           try
           {
               ADManager adMamager = new ADManager();
               if (groupalias.IndexOf("\\") != -1)
               {
                   groupalias = groupalias.Split("\\".ToCharArray())[1];
               }


               if (useralias.IndexOf("\\") != -1)
               {
                   useralias = useralias.Split("\\".ToCharArray())[1];
               }

               DirectoryEntry userEntry = adMamager.SearchADByAlias(useralias, Config.Instance.domainName);
               DirectoryEntry groupEntry = adMamager.SearchADByAlias(groupalias, Config.Instance.domainName);
               adMamager.AddToGroup(userEntry.Path, groupEntry.Path);
           }
           catch (Exception ex)
           {
               throw new Exception(string.Format("Failed to {0} add into group {1} by message ", useralias, groupalias, ex.Message));
           }
       }

       private string GetMeetRoomIDFromUrl(string url)
       {
           return url.Substring(url.LastIndexOf("/") +1);
       }

       private string CreateFiveYearsMeetingRooom(string meetingSubject)
       {
           // Config.Instance.meetingRoomServiceUrl
           Helper.WriteLog("start CreateFiveYearsMeetingRooom with meetingSubject is " + meetingSubject);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with meetingRoomServiceUrl is " + Config.Instance.meetingRoomServiceUrl);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with userNameForCreatingMeetingRoom is " + Config.Instance.userNameForCreatingMeetingRoom);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with passwordForCreatingMeetingRoom is " + Config.Instance.passwordForCreatingMeetingRoom);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with lyncServer is " + Config.Instance.lyncServer);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with domainName is " + Config.Instance.domainName);
           Helper.WriteLog("CreateFiveYearsMeetingRooom with sipForCreatingMeetingRoom is " + Config.Instance.sipForCreatingMeetingRoom);
          var client = Helper.GetMeetingRoomServiceClient(Config.Instance.meetingRoomServiceUrl);
          string meetingRoomUrl = client.CreateFiveYearMeeting(
              Config.Instance.userNameForCreatingMeetingRoom + "#" + meetingSubject,
              Config.Instance.passwordForCreatingMeetingRoom,
              Config.Instance.lyncServer,
              Config.Instance.domainName,
              Config.Instance.sipForCreatingMeetingRoom);

          Helper.WriteLog("End CreateFiveYearsMeetingRooom with meetingRoomUrl " + meetingRoomUrl);
          return meetingRoomUrl;
       }

       //private string GetOUPath()
       //{
       //    string domainName = Config.Instance.domainName;
       //    if (domainName.IndexOf(".") !=-1)
       //    {
       //        domainName = domainName.Substring(0, domainName.IndexOf(".")); 
       //    }

       //    return "OU=" + Config.Instance.chatRoomOU + ",DC=" + domainName + ",DC=com";
       //}

        // Create SG 
       private string CreateSG(string groupName, string ou, string addToGroup)
       {
           ADManager adMamager = new ADManager();
           string path = adMamager.CreateGroup(ou, groupName);
           path = path.Replace("LDAP://", "");
           adMamager.AddToGroup(path, addToGroup);
           return path;    
       }


       private void RemoveSG(string groupName)
       {
           this.RemoveADGroup(groupName);
       }

       private string CreateSite(string chatroomId,string chatRoomName,  SPSite site)
       {
           return Helper.CrateSiteByTemplate("hzWeb#0", chatroomId, chatRoomName, site);
       }

       private void RemoveSite(string siteUrl, SPSite site)
       {
           Helper.RemoveSite(siteUrl, site);
       }

       private void CreateSPGroup(string groupName)
       { 

       }

       private void RemoveSPGroup(string groupName)
       {

       }

       private void CreateRoomInLync(string adminGroupPath,string memberGroupPath,string chatroomId, string memberGroup, string siteUrl)
       {
          var client = Helper.GetChatRoomServiceClient(Config.Instance.chatRoomServiceUrl);
          client.CreatePersistentChatRoom(
              adminGroupPath,
              memberGroupPath,
              siteUrl,
              Config.Instance.persistentChatPool,
              Config.Instance.persistentChatRoomCategory, 
              chatroomId);                            
       }

       private void RemoveRoomInLync(string chatroomName)
       {
           var client = Helper.GetChatRoomServiceClient(Config.Instance.chatRoomServiceUrl);
           client.RemovePersistentChatRoom(Config.Instance.persistentChatPool + "\\" + chatroomName);
       }

       /// <summary>
       /// An item is being updated.
       /// </summary>
       public override void ItemUpdating(SPItemEventProperties properties)
       {
           if (properties.List == null || properties.List.BaseTemplate.ToString() != "999") return;
           Config.webUrl = properties.WebUrl;
           // properties.AfterProperties.ChangedProperties.Add("Title", properties.AfterProperties["RoomName"].ToString());

           SPSecurity.RunWithElevatedPrivileges(delegate()
          {
              this.UpdateSIP(properties);              

              // Update the admin and member group according to users operation  
              string adminADGroup = properties.ListItem["ChatRoomSecurityGroupAdmin"].ToString();
              if (properties.AfterProperties["ChatRoomAdmins"]!=null &&
                  properties.ListItem["ChatRoomAdmins"].ToString().ToUpper() != properties.AfterProperties["ChatRoomAdmins"].ToString().ToUpper() &&
                  !string.IsNullOrEmpty(adminADGroup))
              {
                  UpdateUsers(
                      properties.ListItem["ChatRoomAdmins"].ToString(),
                      properties.AfterProperties["ChatRoomAdmins"].ToString(),
                      properties.Web,
                      adminADGroup);

              }

              string memberADGroup = properties.ListItem["ChatRoomSecurityGroupMember"].ToString();
              if (properties.AfterProperties["ChatRoomMembers"] != null && 
                  properties.ListItem["ChatRoomMembers"].ToString().ToUpper() != properties.AfterProperties["ChatRoomMembers"].ToString().ToUpper() &&
                  !string.IsNullOrEmpty(memberADGroup))
              {
                  UpdateUsers(
                      properties.ListItem["ChatRoomMembers"].ToString(),
                      properties.AfterProperties["ChatRoomMembers"].ToString(),
                      properties.Web,
                      memberADGroup);
              }

              // call ReBindMemebersOfChatRoom
              Helper.WriteLog("call ReBindMemebersOfChatRoom");
              SPListItem currentItem = properties.List.GetItemById(properties.ListItemId);

              // ChatRoomID,ChatRoomSecurityGroupAdmin,ChatRoomSecurityGroupMember,ChatRoomSite
              string adminGroup = "" + currentItem["ChatRoomSecurityGroupMember"];
              string memberGroup = "" + currentItem["ChatRoomSecurityGroupMember"];
              string siteUrl = "" + currentItem["ChatRoomSite"];
              string roomName = "" + currentItem["RoomName"];

              ADManager adMamager = new ADManager();
              DirectoryEntry adminDirectoryEntry = adMamager.SearchADByAlias(adminGroup, Config.Instance.domainName, true);
              if (adminDirectoryEntry == null)
              {
                  Helper.WriteLog("Error: can't find adminGroup:" + adminGroup);
                  return;
              }

              DirectoryEntry memberDirectoryEntry = adMamager.SearchADByAlias(memberGroup, Config.Instance.domainName, true);
              if (memberDirectoryEntry == null)
              {
                  Helper.WriteLog("Error: can't find memberGroup:" + adminGroup);
                  return;
              }

              string adminGroupPath = adminDirectoryEntry.Path.Replace("LDAP://", "");
              string memberGroupPath = memberDirectoryEntry.Path.Replace("LDAP://", "");

              Helper.WriteLog(string.Format("Call ReBindMemebersOfChatRoom with adminGroupPath:{0}, memberGroupPath{1}", adminGroupPath, memberGroupPath));
              var client = Helper.GetChatRoomServiceClient(Config.Instance.chatRoomServiceUrl);
              client.ReBindMemebersOfChatRoom(
                  adminGroupPath,
                  memberGroupPath,
                  siteUrl,
                  Config.Instance.persistentChatPool,
                  Config.Instance.persistentChatRoomCategory,
                  roomName);   

          });
       }

       private void UpdateUsers(string oldUsers, string newUsers, SPWeb web, string adGroup)
       {          
           List<SPUser> oldUserList = GetUserList(oldUsers, web);
           List<SPUser> newUserList = GetUserList(newUsers, web);
           List<SPUser> addUserList = GetUserAMinusB(newUserList, oldUserList);
           List<SPUser> removeUserList = GetUserAMinusB(oldUserList, newUserList);
           ADManager adMamager = new ADManager();

           // DirectoryEntry userEntry = adMamager.SearchADByAlias(alias, Config.Instance.domainName);
           // adMamager.AddToGroup(userEntry.Path, groupPath);
           DirectoryEntry groupEntiry = adMamager.SearchADByAlias(adGroup, Config.Instance.domainName, true);

           // Add new users
           foreach (SPUser user in addUserList)
           {
               string addUserAlias = user.LoginName.Substring(user.LoginName.IndexOf("\\") + 1);
               DirectoryEntry addUserEntity = adMamager.SearchADByAlias(addUserAlias, Config.Instance.domainName);
               adMamager.AddToGroup(addUserEntity.Path, groupEntiry.Path);
           }

           // remove old users
           foreach (SPUser user in removeUserList)
           {
               string removeUserAlias = user.LoginName.Substring(user.LoginName.IndexOf("\\") + 1);
               DirectoryEntry removeUserEntity = adMamager.SearchADByAlias(removeUserAlias, Config.Instance.domainName);
               adMamager.RemoveUserFromGroup(removeUserEntity.Path, groupEntiry.Path);
           }
       }

       private List<SPUser> GetUserAMinusB(List<SPUser> userListA, List<SPUser> userListB)
       {
           List<SPUser> userList = new List<SPUser>();
           foreach (SPUser userA in userListA)
           {
               bool foundResult = false;
               foreach (SPUser userB in userListB)
               {
                   if (userA.ID == userB.ID)
                   {
                       foundResult = true;
                       break;
                   }
               }

               if (!foundResult)
               {
                   userList.Add(userA);
               }
           }

           return userList;
       }

       private List<SPUser> GetUserList(string strUsers, SPWeb web)
       {
           List<SPUser> userList = new List<SPUser>();
           SPFieldUserValueCollection users = new SPFieldUserValueCollection(web, strUsers);
           foreach (SPFieldUserValue user in users)
           {
               SPUser spUser = null;
               if (user.LookupId == -1)
               {
                   spUser = web.EnsureUser(user.LookupValue);
               }
               else
               {
                   spUser = user.User;
               }

               userList.Add(spUser);
           }

           return userList;
       }

       /// <summary>
       /// An item is being deleted.
       /// </summary>
       public override void ItemDeleting(SPItemEventProperties properties)
       {
           if (properties.List == null || properties.List.BaseTemplate.ToString() != "999") return;
           Config.webUrl = properties.WebUrl;
           SPSecurity.RunWithElevatedPrivileges(delegate()
           {
               // Update the admin and member group according to users operation
               Helper.WriteLog("Start remove chat room");
               string adminADGroup = properties.ListItem["ChatRoomSecurityGroupAdmin"].ToString();          
               string memberADGroup = properties.ListItem["ChatRoomSecurityGroupMember"].ToString();
               string siteUrl = properties.ListItem["ChatRoomSite"].ToString();
               Helper.WriteLog("Remove adminADGroup:" + adminADGroup);
               this.RemoveADGroup(adminADGroup);
               Helper.WriteLog("Remove memberADGroup:" + memberADGroup);
               this.RemoveADGroup(memberADGroup);
               Helper.WriteLog("Remove chatroom space:" + siteUrl);
               this.RemoveSite(siteUrl, properties.Web.Site);
               Helper.WriteLog("Remove RemoveChatRoomInLync:" + siteUrl);
               this.RemoveRoomInLync(properties.ListItem["RoomName"].ToString());
               var client = Helper.GetMeetingRoomServiceClient(Config.Instance.meetingRoomServiceUrl);
               var meetingId = properties.ListItem["ChatRoomID"].ToString();
               Helper.WriteLog("RemoveFiveYearMeeting id:" + meetingId);
               client.RemoveFiveYearMeeting(Config.Instance.userNameForCreatingMeetingRoom, 
                   Config.Instance.passwordForCreatingMeetingRoom, 
                   Config.Instance.lyncServer,
                   Config.Instance.domainName,
                   Config.Instance.sipForCreatingMeetingRoom,
                   meetingId);               
           });
       }

       private void RemoveADGroup(string groupName)
       {
           try
           {
               ADManager adMamager = new ADManager();
               DirectoryEntry groupEntiry = adMamager.SearchADByAlias(groupName, Config.Instance.domainName);

               // DirectoryEntry ouEntiry = adMamager.SearchADByAlias(Config.Instance.chatRoomOU, Config.Instance.domainName);
               adMamager.DeleteGroup(Config.Instance.chatRoomOU, groupEntiry.Path);
           }
           catch (Exception ex)
           { 
               SPDiagnosticsCategory category = new SPDiagnosticsCategory("ChatRoomRemove", TraceSeverity.Unexpected, EventSeverity.Error, 123, 123);
               SPDiagnosticsService.Local.WriteTrace(123, category, TraceSeverity.Unexpected, "Remove AD group " + groupName + "failed by :" + ex.Message, null);
           }
       }

       /// <summary>
       /// 已添加项
       /// </summary>
       public override void ItemAdded(SPItemEventProperties properties)
       {
           if (properties.List == null || properties.List.BaseTemplate.ToString() != "999") return;
           base.ItemAdded(properties);     
        SPSecurity.RunWithElevatedPrivileges(delegate()
           {
               using (SPSite site = new SPSite(properties.SiteId))
               {
                   SPWeb web = site.OpenWeb();
                   var listItem = web.Lists[properties.ListId].GetItemById(properties.ListItemId);
                   listItem.BreakRoleInheritance(false);
                   SPUser adminGroup = web.EnsureUser(listItem["ChatRoomSecurityGroupAdmin"].ToString());
                   SPUser memberGroup = web.EnsureUser(listItem["ChatRoomSecurityGroupMember"].ToString());
                   SPUser superAdminGroup = web.EnsureUser(Config.Instance.supperAdminGroup);
                   SPRoleDefinitionCollection roleDefinitions = web.RoleDefinitions;

                   SPRoleAssignment superAdminRoleAssignment = new SPRoleAssignment(superAdminGroup);
                   SPRoleDefinitionBindingCollection superAdminRoleDefBindings = superAdminRoleAssignment.RoleDefinitionBindings;
                   superAdminRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Full Control"));
                   listItem.RoleAssignments.Add(superAdminRoleAssignment);

                   // Add current user |Author
                   SPFieldUserValue userValue = new SPFieldUserValue(web, listItem[SPBuiltInFieldId.Author].ToString());
                   SPUser currentUser = userValue.User;                 
                   SPRoleAssignment currentRoleAssignment = new SPRoleAssignment(currentUser);
                   SPRoleDefinitionBindingCollection currentRoleDefBindings = currentRoleAssignment.RoleDefinitionBindings;
                   currentRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Full Control"));
                   listItem.RoleAssignments.Add(currentRoleAssignment);

                   // SPFieldUserValueCollection
                   SPFieldUserValueCollection admins = new SPFieldUserValueCollection(web, listItem["ChatRoomAdmins"].ToString());
                   SPFieldUserValueCollection members = new SPFieldUserValueCollection(web, listItem["ChatRoomMembers"].ToString());

                   SPRoleAssignment adminRoleAssignment = new SPRoleAssignment(adminGroup);
                   SPRoleDefinitionBindingCollection roleDefBindings = adminRoleAssignment.RoleDefinitionBindings;
                   roleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Full Control"));
                   listItem.RoleAssignments.Add(adminRoleAssignment);

                   SPRoleAssignment memberRoleAssignment = new SPRoleAssignment(memberGroup);
                   SPRoleDefinitionBindingCollection memberRoleDefBindings = memberRoleAssignment.RoleDefinitionBindings;
                   memberRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Read"));
                   listItem.RoleAssignments.Add(memberRoleAssignment);

                   AddPermissonForChatRoomItem(admins, members, listItem, roleDefinitions);
                   listItem.Update();

                   var webUrl = listItem["ChatRoomSite"].ToString();
                   var webId = listItem["ChatRoomID"].ToString();
                   var groupSpaceWeb = site.OpenWeb(webId);
                   groupSpaceWeb.BreakRoleInheritance(false, true);
                   groupSpaceWeb.Update();

                   groupSpaceWeb.RoleAssignments.Add(adminRoleAssignment);
                   memberRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Contribute"));
                   groupSpaceWeb.RoleAssignments.Add(memberRoleAssignment);
                   AddPermissonForSharedSpace(admins, members, roleDefinitions, groupSpaceWeb);
                   groupSpaceWeb.Update();
               }

           });
       }

       private void AddPermissonForSharedSpace(SPFieldUserValueCollection admins, SPFieldUserValueCollection members, SPRoleDefinitionCollection roleDefinitions, SPWeb web)
       {
           foreach (SPFieldUserValue admin in admins)
           {
               SPUser spAdmin = admin.User;
               SPRoleAssignment currentRoleAssignment = new SPRoleAssignment(spAdmin);
               SPRoleDefinitionBindingCollection currentRoleDefBindings = currentRoleAssignment.RoleDefinitionBindings;
               currentRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Full Control"));
               web.RoleAssignments.Add(currentRoleAssignment);
           }


           foreach (SPFieldUserValue member in members)
           {
               SPUser spMemeber = member.User;
               SPRoleAssignment currentRoleAssignment = new SPRoleAssignment(spMemeber);
               SPRoleDefinitionBindingCollection currentRoleDefBindings = currentRoleAssignment.RoleDefinitionBindings;
               currentRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Contribute"));
               web.RoleAssignments.Add(currentRoleAssignment);
           }
       }

       private void AddPermissonForChatRoomItem(SPFieldUserValueCollection admins, SPFieldUserValueCollection members, SPListItem item, SPRoleDefinitionCollection roleDefinitions)
       {
           foreach (SPFieldUserValue admin in admins)
           {
               SPUser spAdmin = admin.User;
               SPRoleAssignment currentRoleAssignment = new SPRoleAssignment(spAdmin);
               SPRoleDefinitionBindingCollection currentRoleDefBindings = currentRoleAssignment.RoleDefinitionBindings;
               currentRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Full Control"));
               item.RoleAssignments.Add(currentRoleAssignment);
           }

           foreach (SPFieldUserValue member in members)
           {
               SPUser spMemeber = member.User;
               SPRoleAssignment currentRoleAssignment = new SPRoleAssignment(spMemeber);
               SPRoleDefinitionBindingCollection currentRoleDefBindings = currentRoleAssignment.RoleDefinitionBindings;
               currentRoleDefBindings.Add(Helper.GetRoleDefinition(roleDefinitions,"Contribute"));
               item.RoleAssignments.Add(currentRoleAssignment);
           }
       }
    }
}
